#include "sysconf.h"
#include <QFile>
#include <QTextStream>
#include <QStringList>
#include <QMap>
#include <QFtp>
#include <stdio.h>
#include "ftputil.h"
#include "QHash"

QList<DevConf> confDevList;
Channel chn[2];
_61850 m61850;
BoxInfo boxInfo;
QMap<QString,LdInfo> updateLds;
FtpUtil ftp;
RunState runState;
QByteArray pstxt;
QByteArray rcstxt;
QByteArray profiletxt;






bool parseDev(QString filepath)
{
    QFile file(filepath);

    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug("打开config/dev.cfg失败");
        return false;
    }

    QTextStream in(&file);
    in.setCodec("utf-8");

    if(!confDevList.isEmpty())
    {
       confDevList.clear();
    }

    while(!in.atEnd())
    {
        QString line=in.readLine();
        QRegExp reg("[\\s]{1,}");
        QStringList fields=line.split(reg);

        if(fields.size()!=4)
        {
            qDebug("解析文件出错，原因：格式不正确");
            return false;
        }

        DevConf temp;
        temp.dev_type=fields.at(0);
        temp.dev_name=fields.at(1);
        temp.datamap_path=fields.at(2);
        temp.maxCount=fields.at(3).toInt();
        temp.num=0;
        temp.chn1=0;
        temp.chn2=0;

        confDevList<<temp;
    }

    file.close();

    return true;

}


bool parseDatamap()
{
    int i=0;

    //判断dev.cfg模板文件是否已经被解析
    if(confDevList.size()==0)
    {
        qDebug("Error:配置文件dev.cfg为空");
        return false;
    }

    for(i=0;i<confDevList.size();i++)
    {
        DevConf dev=confDevList.at(i);

        QFile file(dev.datamap_path);
        if(!file.open(QIODevice::ReadOnly))
        {
            qDebug("%s打开失败",qPrintable(dev.datamap_path));
            return false;
        }

        //qDebug("%s打开成功",qPrintable(dev.datamap_path));

        QTextStream in(&file);
        in.setCodec("utf-8");

        confDevList[i].datamaplist.clear();

        while(!in.atEnd())
        {
            QString line=in.readLine();
            QRegExp reg("[\\s]{1,}");
            QStringList fields=line.split(reg);

            if(fields.size()!=4)
            {
                qDebug("%s:解析文件出错，原因：格式不正确",qPrintable(dev.datamap_path));
                return false;
            }

            DataMap temp;
            temp.devType=fields.at(0);
            temp.key=fields.at(1);
            temp.value=fields.at(2);
            temp.type=fields.at(3);

            confDevList[i].datamaplist<<temp;

        }

        file.close();

    }



    return true;
}


bool createDatamapFile(const QString &filename,QString &error)
{
    int i=0,j=0,k=0;
    QFile file(filename);

    if(!file.open(QIODevice::WriteOnly))
    {
        error.append("创建datamap.cfg时,无法打开文件");
        return false;
    }

    QTextStream out(&file);
    out.setCodec("utf-8");

    qDebug("生成datamap~~~~~~~~~~~~~~");
    for(i=0;i<confDevList.size();i++)
    {
        qDebug("%s:%d",qPrintable(confDevList.at(i).dev_type),confDevList.at(i).num);
        for(j=0;j<confDevList.at(i).num;j++)
        {

            for(k=0;k<confDevList.at(i).datamaplist.size();k++)
            {
                QString str1,str2,str3;
                str2=confDevList.at(i).datamaplist.at(k).value;
                str3=QString("%1%2").arg(j+1).arg(".");
                str2.replace(".",str3);

                str1=m61850.iedName;
                str1.append(confDevList.at(i).datamaplist.at(k).devType);
                str1.append(QString::number(j+1));
                str1.append("\t");
                str1.append(confDevList.at(i).datamaplist.at(k).key);
                str1.append("\t");
                str1.append(str2);
                str1.append("\t");
                str1.append(confDevList.at(i).datamaplist.at(k).type);
                str1.append("\n");

                out<<str1;
            }
        }
    }

    file.close();

    return true;

}



bool createStartup(const QString &filename,QString &error)
{

    QFile file(filename);

    if(!file.open(QIODevice::WriteOnly))
    {
        error.append("创建startup.cfg时,无法打开文件");
        return false;
    }

    QTextStream out(&file);
    out.setCodec("utf-8");

    QString str;
    str.append("SCLFileName	titans_ied.cid\n")
            .append("IEDName	").append(m61850.iedName).append("\n")
            .append("AccessPointName	S1\n")
            .append("ReportScanRate	2.0\n");
    out<<str;
    file.close();
    return true;


}


void clearData()
{
    if(confDevList.size()!=0)
    {
        confDevList.clear();
    }
    m61850.iedName="";
    for(int i=0;i<2;i++)
    {
        chn[i].baud=0;
        chn[i].com_name="";
        chn[i].fac_no=0;
        chn[i].sysdev.clear();
    }
}


bool loadData()
{
    //载入iedName
    QFile file("./dist/mmslite/startup.cfg");

    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug("./dist/mmslite/startup.cfg失败");
        return false;
    }

    QTextStream in(&file);
    in.setCodec("utf-8");


    while(!in.atEnd())
    {
        QString line=in.readLine();
        QRegExp reg("[\\s]{1,}");
        QStringList fields=line.split(reg);

        if(fields.size()!=2)
        {
            qDebug("解析文件出错，原因：格式不正确");
            return false;
        }
        if(fields.at(0).trimmed()=="IEDName")
        {
            m61850.iedName=fields.at(1).trimmed();
            break;
        }


    }
    file.close();

    if(confDevList.isEmpty())
    {
        parseDev("./config/dev.cfg");
        parseDatamap();
    }

    const QString chnfile="./dist/integrate/channel.cfg";
    QFile file1(chnfile);
    if(!file1.open(QFile::ReadWrite|QFile::Text))
    {
        qDebug("open ./dist/integrate/channel.cfg failed!");
        return false;
    }

    QDomDocument doc;
    if(!doc.setContent(&file1))
    {
        qDebug("doucment set content failed!");
        return false;
    }

    QDomElement docElem = doc.documentElement();        //scl
    QDomNodeList channellist = docElem.elementsByTagName("channel");

    //通道1
    for(int i=0;i<2;i++)
    {
        chn[i].sysdev.clear();

        QDomElement channel = channellist.item(i).toElement();      //channel
        chn[i].fac_no=channel.attributeNode("fac_no").value().toInt();
        chn[i].com_name=channel.attributeNode("com_name").value().trimmed();
        chn[i].baud=channel.attributeNode("baud").value().toInt();

        QDomNodeList devList=channel.elementsByTagName("DEV");//DEV

        for(int j=0;j<devList.size();j++)
        {
            QDomElement devDom=devList.item(j).toElement();

            DEV temp;
            temp.devAddr=devDom.attributeNode("dev_addr").value().toInt();
            temp.dev_name=devDom.attributeNode("dev_name").value().trimmed();
            temp.dev_type=devDom.attributeNode("dev_type").value().trimmed();

            updateDevNum(temp.dev_type);

            chn[i].sysdev<<temp;
        }

    }

    return true;

}


bool crateCID(const QString &filename)
{
    const QString srcfile="./config/titans_ied.cid";


    QFile file(srcfile);
    if(!file.open(QFile::ReadWrite|QFile::Text))
    {
        qDebug("open %s failed!",qPrintable(filename));
        return false;
    }

    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        qDebug("doucment set content failed!");
        return false;
    }

    QDomElement docElem = doc.documentElement();        //scl
    QDomNodeList scllist = docElem.elementsByTagName("IED");

    QDomElement scl = scllist.item(0).toElement();      //ied
    scl.setAttribute("name",m61850.iedName);

    QDomNodeList accesspointList=scl.elementsByTagName("AccessPoint");//accesspoint
    QDomElement accesspoint=accesspointList.item(0).toElement(); //accesspoint

    QDomNodeList serverList=accesspoint.elementsByTagName("Server");
    QDomElement server=serverList.item(0).toElement(); //Server

    QDomNodeList lDeviceList=server.elementsByTagName("LDevice");//LDevices

    //server.removeChild(lDeviceList.item(0));
    qDebug("生成icd文件~~~~~~~~~~~~~~~~~~~");

    for(int i=0;i<confDevList.size();i++)
    {
        DevConf temp=confDevList.at(i);

        qDebug("%s:%d",qPrintable(temp.dev_type),temp.num);

        int maxDev=2;
        QString dType;
        if(temp.dev_type=="TEP-I-G")
        {
            maxDev=3;
            dType="ZLP";
        }
        else if(temp.dev_type=="TEP-G-E")
        {
            maxDev=10;
            dType="JYJC";
        }
        else if(temp.dev_type=="TATS-I-A")
        {
            maxDev=2;
            dType="ATS";
        }
        else if(temp.dev_type=="TUPS-I-A")
        {
            maxDev=2;
            dType="UPS";
        }
        else if(temp.dev_type=="TEP-B-D")
        {
            maxDev=2;
            dType="DCZ";
        }

        int j=0;
        for(j=(temp.num+1);j<=maxDev;j++)
        {
            QString inst;
            inst=QString("%1%2").arg(dType).arg(j);


            for(int k=0;k<lDeviceList.size();k++)
            {
                if(lDeviceList.item(k).toElement().attribute("inst").trimmed()==inst)
                {
                    server.removeChild(lDeviceList.item(k));
                    break;
                }
            }

        }

    }

    int zlpnum=0,jyjcnum=0,dcznum=0,upsnum=0,atsnum=0;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<chn[i].sysdev.size();j++)
        {
            QString dType="";
            QString devName="";
            if(chn[i].sysdev.at(j).dev_type=="TEP-I-G")
            {
                zlpnum++;
                dType="ZLP";
                devName=QString("%1%2").arg(dType).arg(zlpnum);
            }
            else if(chn[i].sysdev.at(j).dev_type=="TEP-G-E")
            {
                jyjcnum++;
                dType="JYJC";
                devName=QString("%1%2").arg(dType).arg(jyjcnum);
            }
            else if(chn[i].sysdev.at(j).dev_type=="TATS-I-A")
            {
                atsnum++;
                dType="ATS";
                devName=QString("%1%2").arg(dType).arg(atsnum);
            }
            else if(chn[i].sysdev.at(j).dev_type=="TUPS-I-A")
            {
                upsnum++;
                dType="UPS";
                devName=QString("%1%2").arg(dType).arg(upsnum);
            }
            else if(chn[i].sysdev.at(j).dev_type=="TEP-B-D")
            {
                dcznum++;
                dType="DCZ";
                devName=QString("%1%2").arg(dType).arg(dcznum);
            }

            for(int k=0;k<lDeviceList.size();k++)
            {
                if(lDeviceList.item(k).toElement().attribute("inst").trimmed()==devName)
                {
                    QDomNodeList ln0List=lDeviceList.item(k).toElement().elementsByTagName("LN0");
                    QDomElement ln0=ln0List.item(0).toElement(); //Server

                    QDomNodeList doiList=ln0.elementsByTagName("DOI");//LDevices

                    for(int m=0;m<doiList.size();m++)
                    {
                        if(doiList.item(m).toElement().attribute("name").trimmed()=="channel")
                        {
                            QDomNodeList daiList=doiList.item(m).toElement().elementsByTagName("DAI");

                            for(int n=0;n<daiList.size();n++)
                            {
                                if(daiList.item(n).toElement().attribute("name").trimmed()=="stVal")
                                {

                                    QDomElement el = daiList.item(n).toElement().elementsByTagName("Val").item(0).toElement();  //tag为key的节点
                                    QDomNode oldnode = el.firstChild();           //标签之间的内容作为节点的子节点出现，得到原来的子节点
                                    el.firstChild().setNodeValue(QString::number(chn[i].fac_no));   //用提供的value值来设置子节点的内
                                    QDomNode newnode = el.firstChild();               //值修改过后的子节点
                                    el.replaceChild(newnode,oldnode);
                                }
                            }
                        }

                        if(doiList.item(m).toElement().attribute("name").trimmed()=="saddr")
                        {
                            QDomNodeList daiList=doiList.item(m).toElement().elementsByTagName("DAI");

                            for(int n=0;n<daiList.size();n++)
                            {
                                if(daiList.item(n).toElement().attribute("name").trimmed()=="stVal")
                                {
                                    //qDebug("addr:%s",qPrintable(daiList.item(n).toElement().elementsByTagName("Val").item(0).toElement().text()));
                                    QDomElement el = daiList.item(n).toElement().elementsByTagName("Val").item(0).toElement();  //tag为key的节点
                                    QDomNode oldnode = el.firstChild();           //标签之间的内容作为节点的子节点出现，得到原来的子节点
                                    el.firstChild().setNodeValue(QString::number(chn[i].sysdev.at(j).devAddr));   //用提供的value值来设置子节点的内
                                    QDomNode newnode = el.firstChild();               //值修改过后的子节点
                                    el.replaceChild(newnode,oldnode);

                                }
                            }
                        }
                    }
                    break;
                }
            }
        }

    }

    QFile outfile(filename);
    if(!outfile.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        return false;
    }
    QTextStream out(&outfile);
    out.setCodec("utf-8");
    doc.save(out,4);

    outfile.close();
    file.close();

    return true;

}

void updateDevNum(const QString &devType)
{
    for(int i=0;i<confDevList.size();i++)
    {
        if(devType==confDevList.at(i).dev_type)
        {
            confDevList[i].num++;
        }
    }
}


void updateIEDNameCid(const QString &iedname)
{

    const QString srcfile="./dist/mmslite/titans_ied.cid";


    QFile file(srcfile);
    if(!file.open(QFile::ReadWrite|QFile::Text))
    {
        qDebug("open %s failed!",qPrintable(srcfile));
        return ;
    }

    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        qDebug("doucment set content failed!");
        return ;
    }

    QDomElement docElem = doc.documentElement();        //scl
    QDomNodeList scllist = docElem.elementsByTagName("IED");

    QDomElement scl = scllist.item(0).toElement();      //ied
    scl.setAttribute("name",iedname);

    QDomNodeList accesspointList=scl.elementsByTagName("AccessPoint");//accesspoint
    QDomElement accesspoint=accesspointList.item(0).toElement(); //accesspoint

    QDomNodeList serverList=accesspoint.elementsByTagName("Server");
    QDomElement server=serverList.item(0).toElement(); //Server

    QDomNodeList lDeviceList=server.elementsByTagName("LDevice");//LDevices

    for(int i=0;i<lDeviceList.size();i++)
    {
        QDomElement ld=lDeviceList.item(i).toElement(); //Server
        QString inst=ld.attribute("inst");
        if(updateLds.contains(inst))
        {
            QMap<QString, LdInfo>::const_iterator i = updateLds.find(inst);
            LdInfo ldInfo=(LdInfo)i.value();
            ld.setAttribute("desc",chn[ldInfo.chnIndex].sysdev[ldInfo.devIndex].dev_name);

            QDomNodeList ln0List=ld.elementsByTagName("LN0");

            QDomElement ln0=ln0List.item(0).toElement(); //Server

            QDomNodeList doiList=ln0.elementsByTagName("DOI");//LDevices

            for(int m=0;m<doiList.size();m++)
            {
                if(doiList.item(m).toElement().attribute("name").trimmed()=="channel")
                {
                    QDomNodeList daiList=doiList.item(m).toElement().elementsByTagName("DAI");

                    for(int n=0;n<daiList.size();n++)
                    {
                        if(daiList.item(n).toElement().attribute("name").trimmed()=="stVal")
                        {

                            QDomElement el = daiList.item(n).toElement().elementsByTagName("Val").item(0).toElement();  //tag为key的节点
                            QDomNode oldnode = el.firstChild();           //标签之间的内容作为节点的子节点出现，得到原来的子节点
                            el.firstChild().setNodeValue(QString::number(chn[ldInfo.chnIndex].fac_no));   //用提供的value值来设置子节点的内
                            QDomNode newnode = el.firstChild();               //值修改过后的子节点
                            el.replaceChild(newnode,oldnode);
                        }
                    }
                }

                if(doiList.item(m).toElement().attribute("name").trimmed()=="saddr")
                {
                    QDomNodeList daiList=doiList.item(m).toElement().elementsByTagName("DAI");

                    for(int n=0;n<daiList.size();n++)
                    {
                        if(daiList.item(n).toElement().attribute("name").trimmed()=="stVal")
                        {
                            //qDebug("addr:%s",qPrintable(daiList.item(n).toElement().elementsByTagName("Val").item(0).toElement().text()));
                            QDomElement el = daiList.item(n).toElement().elementsByTagName("Val").item(0).toElement();  //tag为key的节点
                            QDomNode oldnode = el.firstChild();           //标签之间的内容作为节点的子节点出现，得到原来的子节点
                            el.firstChild().setNodeValue(QString::number(chn[ldInfo.chnIndex].sysdev.at(ldInfo.devIndex).devAddr));   //用提供的value值来设置子节点的内
                            QDomNode newnode = el.firstChild();               //值修改过后的子节点
                            el.replaceChild(newnode,oldnode);

                        }
                    }
                }
            }
        }
    }

    file.close();

    QFile outfile(srcfile);
    if(!outfile.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        return ;
    }
    QTextStream out(&outfile);
    out.setCodec("utf-8");
    doc.save(out,4);
}


void updateChannel()
{

    const QString chnfile="./dist/integrate/channel.cfg";
    QFile file1(chnfile);
    if(!file1.open(QFile::ReadWrite|QFile::Text))
    {
        qDebug("open ./dist/integrate/channel.cfg failed!");
        return ;
    }

    QDomDocument doc;
    if(!doc.setContent(&file1))
    {
        qDebug("doucment set content failed!");
        return ;
    }

    QDomElement docElem = doc.documentElement();        //scl
    QDomNodeList channellist = docElem.elementsByTagName("channel");

    //通道1
    for(int i=0;i<2;i++)
    {
       // chn[i].sysdev.clear();

        QDomElement channel = channellist.item(i).toElement();      //channel
        channel.setAttribute("com_name",chn[i].com_name);
        channel.setAttribute("baud",QString::number(chn[i].baud));

        QDomNodeList devList=channel.elementsByTagName("DEV");//DEV

        for(int j=0;j<devList.size();j++)
        {
            QDomElement devDom=devList.item(j).toElement();
            devDom.setAttribute("dev_addr",QString::number(chn[i].sysdev.at(j).devAddr));
            devDom.setAttribute("dev_name",chn[i].sysdev.at(j).dev_name);
        }

    }

    file1.close();
    QFile outfile(chnfile);
    if(!outfile.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        return ;
    }
    QTextStream out(&outfile);
    out.setCodec("utf-8");
    doc.save(out,4);

}


bool loadBoxInfo(const QString &filename)
{
    QFile file(filename);

    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug("打开config/box.cfg失败");
        return false;
    }

    QTextStream in(&file);
    in.setCodec("utf-8");

    while(!in.atEnd())
    {
        QString line=in.readLine();
        QRegExp reg("[\\s]{1,}");
        QStringList fields=line.split(reg);

        if(fields.size()!=2)
        {
            qDebug("解析文件出错，原因：格式不正确");
            return false;
        }

/*        if(fields.at(0)=="ip1")
        {
            boxInfo.ip1=fields.at(1);
        }
        else if(fields.at(0)=="ip2")
        {
            boxInfo.ip2=fields.at(1);
        }
        else */
        if(fields.at(0)=="user")
        {
            boxInfo.user=fields.at(1);
        }
        else if(fields.at(0)=="psw")
        {
            boxInfo.psw=fields.at(1);
        }
        else if(fields.at(0)=="ftpip")
        {
            boxInfo.dfip=fields.at(1);
        }

    }

    file.close();

    return true;
}



bool updateBoxInfo()
{
    QFile file("./config/box.cfg");

    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug("创建box.cfg时,无法打开文件");
        return false;
    }

    QTextStream out(&file);
    out.setCodec("utf-8");

    QString str;
    str.append("ftpip\t").append(boxInfo.dfip).append("\n")
            //.append("ip1\t").append(boxInfo.ip1).append("\n")
            //.append("ip2\t").append(boxInfo.ip2).append("\n")
            .append("user\t").append(boxInfo.user).append("\n")
            .append("psw\t").append(boxInfo.psw).append("\n");
    out<<str;
    file.close();
    return true;
}


QString ldeviceName(int chnIndex,int devIndex)
{
    int start1=0,start2=0,index=0;
    int i=0;
    bool isExist1=false,isExist2=false;
    int total1=0,total2=0;

    for(i=0;i<chn[0].sysdev.size();i++)
    {
        if(chn[chnIndex].sysdev.at(devIndex).dev_type==chn[0].sysdev.at(i).dev_type)
        {
            total1++;
            if(!isExist1)
            {
                isExist1=true;
                start1=i;
            }

        }
    }

    for(i=0;i<chn[1].sysdev.size();i++)
    {
        if(chn[chnIndex].sysdev.at(devIndex).dev_type==chn[1].sysdev.at(i).dev_type)
        {
            total2++;
            if(!isExist2)
            {
                isExist2=true;
                start2=i;
            }
        }
    }


    if(chnIndex==0)
    {
        index=devIndex-start1;
    }
    if(chnIndex==1)
    {
        index=total1+(devIndex-start2);
    }

    DEV temp=chn[chnIndex].sysdev.at(devIndex);

    QString ldname;
    if(temp.dev_type=="TEP-I-G")
    {
        ldname=QString("ZLP%1").arg(index+1);
    }
    else if(temp.dev_type=="TEP-G-E")
    {
        ldname=QString("JYJC%1").arg(index+1);
    }
    else if(temp.dev_type=="TATS-I-A")
    {
        ldname=QString("ATS%1").arg(index+1);
    }
    else if(temp.dev_type=="TUPS-I-A")
    {
        ldname=QString("UPS%1").arg(index+1);
    }
    else if(temp.dev_type=="TEP-B-D")
    {
        ldname=QString("DCZ%1").arg(index+1);
    }

    return ldname;
}
